package org.finmanager.statistics;

import org.finmanager.core.Item;
import org.finmanager.data.CategoryList;
import org.finmanager.data.ItemList;

import javax.swing.table.AbstractTableModel;
import java.util.Calendar;

/**
 * Created by Kelvin on 13/4/2014.
 */

//Defining models which will be used in ItemDistributionController.java
public class ItemDistributionModel extends AbstractTableModel {
	private ItemList itemList;
	private CategoryList categoryList;

	private Calendar calendar = Calendar.getInstance();

	private Double[][] data;

	public ItemDistributionModel(StatisticsModel statisticsModel) {
		this.itemList = statisticsModel.getItemList();
		this.categoryList = statisticsModel.getCategoryList();

		updateData();
	}

	@Override
	public int getRowCount() {
		return categoryList.getCategoryCount();
	}

	@Override
	public int getColumnCount() {
		return 31 + 1;
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		if (columnIndex == 0) return categoryList.getCategory(rowIndex);
		return data[rowIndex][columnIndex - 1];
	}

	@Override
	public String getColumnName(int column) {
		return column == 0 ? "Category" : Integer.toString(column);
	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return false;
	}

	@Override
	public Class<?> getColumnClass(int columnIndex) {
		if (columnIndex == 0) return String.class;
		return Double.class;
	}

	private void updateData() {
		data = new Double[categoryList.getCategoryCount()][31];

		for (int i = 0; i < categoryList.getCategoryCount(); i++) {
			for (int j = 0; j < 31; j++) {
				data[i][j] = 0.0;
			}
		}

		for (Item item : itemList.getList()) {
			if (checkItemTimeConstraint(item)) {
				int c = categoryList.getList().indexOf(item.getCategory());
				data[c][item.getDayOfMonth() - 1] += item.getAmount();
			}
		}
	}

	private boolean checkItemTimeConstraint(Item item) {
		return (item.getYear() == calendar.get(Calendar.YEAR) && item.getMonth() == calendar.get(Calendar.MONTH));
	}

	@Override
	public void fireTableDataChanged() {
		updateData();
		super.fireTableDataChanged();
	}

	public void increaseMonth() {
		calendar.add(Calendar.MONTH, 1);
		fireTableDataChanged();
	}

	public void decreaseMonth() {
		calendar.add(Calendar.MONTH, -1);
		fireTableDataChanged();
	}

	public void setCalendar(Calendar calendar) {
		this.calendar = calendar;
		fireTableDataChanged();
	}

	public Calendar getCalendar() {
		return calendar;
	}
}
